use 5.10.0;
use strict;

package Graphics::SVG::Element;
use Carp;
use Exporter 'import';
our %EXPORT_TAGS = (
	basic	=> [qw(default_new attr textout append default_attr
			add_svg_tag create add_child)],
	noattr	=> [qw(handle_attr)],
);

Exporter::export_ok_tags(qw/basic noattr/);
push our @EXPORT_OK, qw/new/;

use constant handle_attr=>\&default_attr;

*new = *default_new = sub {
	my ($cls, %attr) = @_;
	my $self = { attr=>{} };
	bless $self, $cls;

	my $kids = delete $attr{kids};

	while (my ($k, $v) = each %attr) {
		if ($k eq 'kids') {
			$kids = $v;
		} else {
			$self->attr($k, $v)
		}
	}
	if ($kids) {
		$self->add_child(@$_) for @$kids
	}
	$self;
};

sub default_attr {
	my ($self, $name, $value) = @_;
	if (defined $value) {
		$self->{attr}{$name} = $value;
	} else {
		return $self->{attr}{$name}
	}
}

sub attr {
	my ($self, $name, $value) = @_;
	goto $self->handle_attr($name) // \&default_attr;
}

sub append { push @{shift->{kids}}, @_ }

sub textout {
	my $self = shift;
	my $depth = shift // 0;
	my @out = ("\t" x $depth, "<${$self->tag}");
	for (sort keys %{$self->{attr}}) {
		push @out, " $_=\"".$self->attr($_).'"';
	}
	if (!defined @{$self->{kids}}) {
		push @out, " />\n";
	} else {
		push @out, ">\n";
		for (@{$self->{kids}}) {
			push @out, $_->textout($depth+1);
		}
		push @out, "\t"x $depth, "</${$self->tag}>\n";
	}
	join('', @out);	
}

my %tags;
sub add_svg_tag {
	my ($t, $pkg) = (shift, caller);
	$tags{$t} = $pkg;

	no strict 'refs';
	*{"$pkg\::tag"} = sub { \$t };
}

sub create {
	my $self = shift;
	my $tag = shift;
	my $pkg = $tags{$tag}
		or croak "No creation function for element '$tag'";
	$pkg->new(@_)
}

sub add_child { $_[0]->append(&create) }

1;

